package com.tengju.user.infrastructure.persistence.es;

import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.domain.model.user.UserInfo;
import com.tengju.user.domain.model.user.UserInfoRepository;
import com.tengju.user.domain.service.UserDocService;
import com.tengju.user.domain.shared.BasePage;
import com.tengju.user.infrastructure.external.RemoteUserExternalService;
import com.tengju.user.infrastructure.persistence.mybatis.mapper.dealer.custom.UserInfoDOCustomMapper;
import com.tengju.user.infrastructure.repository.convert.UserConvert;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class UserDocServiceImpl implements UserDocService {

    private final UserInfoRepository userInfoRepository;
    private final RemoteUserExternalService remoteUserExternalService;
    private final UserInfoDOCustomMapper userInfoDOCustomMapper;


    @Override
    public UserInfo searchUserByIdCodeOrMobile(UserIdCode idCode, String mobile) {
        UserInfo result = null;
        if (idCode != null) {
            UserInfo dealerInfo = remoteUserExternalService.getByIdCode(idCode);
            if (dealerInfo != null && dealerInfo.getAbmLevel() != null && dealerInfo.getAbmLevel() == 5) {
                result = dealerInfo;
            }
        } else if (!StringUtils.isBlank(mobile)) {
            UserInfo dealerInfo = remoteUserExternalService.getByWholeMobile(mobile);
            if (dealerInfo != null && dealerInfo.getAbmLevel() != null && dealerInfo.getAbmLevel() == 5) {
                result = dealerInfo;
            }
        }
        if (result != null && result.getIdCode() != null) {
            UserInfo userInfo = userInfoRepository.getByIdCode(new UserIdCode(result.getIdCode().getValue()));
            if(userInfo == null){
                userInfo = new UserInfo(result.getIdCode());
            }
            userInfo.completeInfo(result.getWholePhoneNumber(),result.getName(),result.getNickName(),result.getPidCode());
            return userInfo;
        }
        return null;
    }

    @Override
    public List<UserInfo> searchUserByIdCodes(List<UserIdCode> idCodeList) {
        if (CollectionUtils.isEmpty(idCodeList)) {
            return Collections.emptyList();
        }
        List<UserInfo> userInfoList = userInfoRepository.batchGetUserInfo(idCodeList);
        Map<Long, UserInfo> userInfoDOMap = userInfoList.stream()
                .collect(Collectors.toMap(k -> k.getIdCode().getValue(), v -> v, (v1, v2) -> v1));
        List<Long> userIdList = idCodeList.stream().map(UserIdCode::getValue).collect(Collectors.toList());
        List<UserInfo> externalUsers = remoteUserExternalService.getDealerByIdList(userIdList.stream()
                .map(UserIdCode::new)
                .collect(Collectors.toList())
        );
        Map<Long, UserInfo> externalUserMap = externalUsers.stream()
                .collect(Collectors.toMap(k -> k.getIdCode().getValue(), Function.identity()));
        List<UserInfo> result = new ArrayList<>();
        for (UserIdCode idCode : idCodeList) {
            if (!externalUserMap.containsKey(idCode.getValue())) {
                continue;
            }
            UserInfo dealer = externalUserMap.get(idCode.getValue());
            UserInfo userInfo = userInfoDOMap.getOrDefault(idCode.getValue(), new UserInfo(idCode));
            userInfo.completeInfo(dealer.getWholePhoneNumber(), dealer.getName(), dealer.getNickName(), dealer.getPidCode());
            result.add(userInfo);
        }
        return result;
    }

    @Override
    public BasePage<UserInfo> listPageStarUser(UserIdCode queryIdCode, String mobile, String nickName, Integer starLevel, int offset, int pageSize) {
        BasePage<UserInfo> result = new BasePage<>();
        UserInfo userInfo = searchUserByIdCodeOrMobile(queryIdCode, mobile);
        if (userInfo != null) {
            result.setDatas(Collections.singletonList(userInfo));
            result.setTotal(1);
            return result;
        }
        if (queryIdCode != null || StringUtils.isNotBlank(mobile) || StringUtils.isNotBlank(nickName)) {
            return result;
        }
        List<Long> idCodes = userInfoDOCustomMapper.listIdCodeByStarLevel(starLevel, offset, pageSize);
        List<UserInfo> userInfoList = searchUserByIdCodes(idCodes.stream()
                .filter(Objects::nonNull)
                .map(UserConvert::decryptIdCode)
                .collect(Collectors.toList()));
        int total = userInfoDOCustomMapper.countByStarLevel(starLevel);
        result.setDatas(userInfoList);
        result.setTotal(total);
        return result;
    }


    @Override
    public UserInfo getByIdCode(UserIdCode idCode) {
        return remoteUserExternalService.getByIdCode(idCode);
    }

    @Override
    public List<Long> listBlackChildIdCode(Long idCode) {
        return remoteUserExternalService.listBlackChildIdCode(idCode);
    }


}
